package com.sfchen.cloud.exceptionheader;

import com.sfchen.cloud.exception.BizException;
import com.sfchen.cloud.utils.JsonData;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;


@RestControllerAdvice
@Slf4j
public class CustomExceptionHeader {

    @ExceptionHandler(value = Exception.class)
    public JsonData<Void> header(Exception e) {
        if (e instanceof BizException bizException) {
            log.error("业务异常：{}", bizException.getMessage());
            return JsonData.buildCodeAndMsg(bizException.getCode(), bizException.getMessage());
        } else {
            log.error("[系统异常] {}", e.getMessage());
            return JsonData.buildError(e.getMessage());
        }
    }


    /**
     * 使用validation的参数校验注解，参数校验不通过抛的异常处理
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public JsonData<Void> handleValidationExceptions(MethodArgumentNotValidException se,
                                                     HttpServletResponse response) {
        String code = se.getBindingResult().getFieldError().getCode();
        String field = se.getBindingResult().getFieldError().getField();
        String msg = se.getBindingResult().getFieldError().getDefaultMessage();
        log.error("[ 参数校验异常 ] {}", se.getMessage());
        log.error("[ 参数校验异常 ] code {} field {}", code, field);
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        return JsonData.buildCodeAndMsg(-10422, msg);
    }


    @ExceptionHandler(value = ConstraintViolationException.class)
    public JsonData<Void> argumentNotValidErrorHandler(ConstraintViolationException se,
                                                       HttpServletResponse response) {
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        StringBuilder sb = new StringBuilder();
        for (ConstraintViolation<?> violation : se.getConstraintViolations()) {
            String field = violation.getPropertyPath().toString();
//      Class<?> annotationType = violation.getConstraintDescriptor().getAnnotation().annotationType();
            sb.append(field).append(":").append(violation.getMessage()).append(";");
            log.error("[ 参数校验异常 ] {}", field);
        }
        log.error("[ 参数校验异常 ] {}", se.getMessage());
        log.error("[ 参数校验异常 ]  field list {}", sb);
        return JsonData.buildCodeAndMsg(-10422, "错误字段为：" + sb);
    }


    /**
     * 接收参数格式转换异常
     */
    @ExceptionHandler(value = HttpMessageNotReadableException.class)
    public JsonData<Void> argumentNotValidError2Handler(HttpMessageNotReadableException se,
                                                        HttpServletResponse response) {
        response.setStatus(HttpStatus.BAD_REQUEST.value());

        log.error("[ 参数校验异常 ] {}", se.getMessage());
        log.error("[ 参数校验异常 ]   field list {}", se.getMessage());
        return JsonData.buildCodeAndMsg(-10422, "参数转换错误! ");
    }

}



